package com.lyb269.guava.rateLimiter;

import com.google.common.util.concurrent.RateLimiter;
import org.junit.Test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RateLimiterTest {

    @Test
    public void testAcquire(){

        //每秒发放一个令牌
        RateLimiter rateLimiter = RateLimiter.create(1);
        for (int i = 1; i < 5; i++){
            //该方法会被阻塞,直到获取请求
            //acquire(int permits) 从RateLimiter获取指定许可数,这里每次获取 i许可
            double  waitTime = rateLimiter.acquire(i);
            System.out.println("当前时间戳:"+System.currentTimeMillis()+";需获取的令牌数:"+i+";等待时间:"+waitTime);

            //当前时间戳:1582081509625;需获取的令牌数:1;等待时间:0.0
            //当前时间戳:1582081510626;需获取的令牌数:2;等待时间:0.998608
            //当前时间戳:1582081512626;需获取的令牌数:3;等待时间:1.997178
            //当前时间戳:1582081515625;需获取的令牌数:4;等待时间:2.999229

            //预消费模式,比如获取令牌2个的是否,是上一个获取令牌预消费了1个,类推
        }
    }



    @Test
    public void testLimit() throws InterruptedException {
        // 创建RateLimier并且限制每秒5个令牌
        RateLimiter rateLimiter = RateLimiter.create(5.0);
        Thread.sleep(1000);// sleep 1秒,保证 rateLimiter 有足够时间放足5个令牌
        //起20个线程,模拟20个并发,对应那边限流,每秒只能5个
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(20);
        for(int i = 0; i < 20; i++) {
            fixedThreadPool.submit(() -> {
                String threadName = Thread.currentThread().getName();
                boolean flag = rateLimiter.tryAcquire();        //tryAcquire()方法,尝试获取令牌,true/false
                System.out.println("请求:"+threadName+" --> 获取令牌: "+flag);
            });
        }
        fixedThreadPool.shutdown();
        //请求:pool-1-thread-3 --> 获取令牌: true    //请求:pool-1-thread-1 --> 获取令牌: true
        //请求:pool-1-thread-2 --> 获取令牌: true    //请求:pool-1-thread-4 --> 获取令牌: true
        //请求:pool-1-thread-5 --> 获取令牌: true    //请求:pool-1-thread-6 --> 获取令牌: true
        //请求:pool-1-thread-7 --> 获取令牌: false   //请求:pool-1-thread-8 --> 获取令牌: false
        //请求:pool-1-thread-9 --> 获取令牌: false   //请求:pool-1-thread-10 --> 获取令牌: false
        //请求:pool-1-thread-11 --> 获取令牌: false  //请求:pool-1-thread-12 --> 获取令牌: false
        //请求:pool-1-thread-13 --> 获取令牌: false  //请求:pool-1-thread-14 --> 获取令牌: false
        //请求:pool-1-thread-15 --> 获取令牌: false  //请求:pool-1-thread-16 --> 获取令牌: false
        //请求:pool-1-thread-17 --> 获取令牌: false  //请求:pool-1-thread-18 --> 获取令牌: false
        //请求:pool-1-thread-19 --> 获取令牌: false  //请求:pool-1-thread-20 --> 获取令牌: false

        //6个请求成功,其它请求都没有拿到令牌,这是因为预消费模式,始终比预设的多一个令牌
    }



}
